#pragma once

#include "vision_global.h"
#include <string>
#include <vector>
#include <QString>
#include "opencv2/opencv.hpp"
#include "HalconCpp.h"
using namespace HalconCpp;

// 基于形状定位模块

typedef struct MatchResult
{
	// 匹配后坐标
	double x;
	double y;
	// 匹配分数
	double score;
	// 旋转角度
	double rotAngle;
	// 缩放系数
	double scale;
	// 多模板情况下对应模板id
	int modelId;

	// 机器人坐标系坐标:图像坐标转换后-需要标定
	double rx;
	double ry;

	// 结果序号
	int index;
}*PMatchResult;


// shapebased 模板训练参数
typedef struct ShapeModelParams
{
	HTuple numLevels = "auto";
	double angleStart = -0.39;
	double angleExtent = 0.79;
	HTuple angleStep = "auto";
	double scaleMin = 0.9;
	double scaleMax = 1.1;
	HTuple scaleStep = "auto";
	HTuple optimization = "auto";
	HString metric = "use_polarity";
	HTuple contrast = "auto";
	HTuple minContrast = "auto";

}*PShapeModelParam;

// 模板运行匹配参数
typedef struct ShapeMatchParams
{
	double angleStart;
	double angleExtent;
	double scaleMin;
	double scaleMax;
	double minScore;
	int numMatches;
	double maxOverlap;
	std::string subPixel;
	int numLevels;
	double greediness;
}*PShapeMatchParams;

using MatchResultList = std::vector<MatchResult>;

class VISION_EXPORT MatchShapeBased
{	
public:
	MatchShapeBased();
	~MatchShapeBased();

	int execute(cv::Mat src);

	void setRoi(cv::Rect roi) { searchRoi_ = roi; };

	double getExeTime() { return inspectTime_; }

	int createScaledShapeModel(cv::Mat src, cv::Rect roi);

	bool loadModel(std::string modelPath);
	bool loadModels(QString modelDir);	// 多模板加载
	void saveModel(const char* modelPath);	// 保存模板

	void setModelRoi(cv::Rect roi) { modelRoi_ = roi; };
	void setSearchRoi(cv::Rect roi) { searchRoi_ = roi; };
	cv::Rect getSearchRoi() { return searchRoi_; }

	void setDrawResult(bool draw)	{ drawResults_ = draw; }
	bool isDrawResult() { return drawResults_; }

	HShapeModel* getMultShapeModel() { return (HShapeModel*)multShapeModels_.Tools(); }

protected:	
	MatchResult* findBestResult();

	void findObjects(HImage src);

	// 绘制结果
	void drawMatchResult(cv::Mat src, bool srcChanged=false);

private:
	double inspectTime_ = 0;	// 总检测时间
	cv::Mat resultImage_;		// 将结果绘制在新图像上，保持原图不变化

	MatchResultList allResults_;
	MatchResult* selectResult_ = nullptr;
	bool drawResults_ = false;

	cv::Rect modelRoi_;		// 建模时roi
	cv::Rect searchRoi_;	// 搜索时roi
	HRegion matchRoi_;		// 匹配时roi: searchRoi_ -> matchRoi_

	int matchCount_ = 0;
	HShapeModel shapeModel_;			// 单模板定位
	HShapeModelArray multShapeModels_;	// 多模板定位
	std::vector<HXLDCont> allModelContours_;    // 保存所有模板轮廓
};

